home *** CD-ROM | disk | FTP | other *** search
- Subject: v17i066: Zoo archive program, Part03/10
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Rahul Dhesi <bsu-cs!dhesi@iuvax.cs.indiana.edu>
- Posting-number: Volume 17, Issue 66
- Archive-name: zoo2/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 10)."
- # Wrapped by rsalz@papaya.bbn.com on Thu Feb 2 18:03:58 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Install' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Install'\"
- else
- echo shar: Extracting \"'Install'\" \(7622 characters\)
- sed "s/^X//" >'Install' <<'END_OF_FILE'
- X
- X
- X INSTALLATION
- X
- X
- XThis document explains how to compile and install the zoo archiver.
- X
- XGenerally, you will not build zoo by directly invoking the supplied
- Xmakefile. Instead, you will execute one of the supplied scripts, or
- Xcreate a suitable script. Each supplied script has a name beginning
- Xwith the characters "mk" and is executed with the command
- X"sh scriptname" or "csh scriptname". All the scripts listed below
- Xworked correctly with version 1.50 of zoo. All of them except mkx68 and
- Xmkx86 are also known to work correctly for versions 1.71, 2.00, and
- X2.01.
- X
- Xmksysv This is for any system running System V Release 2 or something
- X reasonably compatible. It is known to work on the *T&T **IX
- X PC (also known as the 3B1 or the *T&T 7300) running software
- X revision 3.0. It should also work on more recent versions of
- X Xenix. On older machine architectures this script may need to
- X be revised to add a `-Ml' switch or equivalent to cause the
- X large memory model to be used. For Microport System V/AT and
- X Xenix see also descriptions for mkuport, mkx86, and mkx68.
- X
- Xmkbsd This is for 4.3BSD. It is known to work on a VAX-11/785 run-
- X ning 4.3BSD straight from Berkeley.
- X
- Xmkuport For Microport System V/AT. This script includes the -Ml
- X switch so that the large memory model is used.
- X
- Xmkx68 This script is for Xenix/68000. It is known to work with zoo
- X version 1.50 on a Radio Shack Model 16 running Xenix version
- X 3.01.01. It takes care of problems in the C compiler and in
- X the include files related to incorrect handling of the `void'
- X data type. However, since this version of Xenix does not have
- X the memset() library function, the line "#define MEMSET" may
- X first need to be commented out from the group of symbol defin-
- X itions for SYS_V in the file ``options.h''. You may also need
- X to add the switch "-F 6000" (or some other reasonable value
- X instead of 6000) to the loader to make it allocate a bigger
- X stack.
- X
- Xmkx86 This script is for Xenix for 80286 systems. It is known to
- X work (for zoo version 1.50) on an Intel 310/286 running Xenix
- X 3.4 and an AT running SCO Xenix 2.2. It causes the large
- X memory model to be used and sufficient stack space to be allo-
- X cated at load time.
- X
- Xdescrip.mms This is a makefile suitable for use on VAX/VMS systems with
- X DEC's version of make, called MMS. It is believed to work on
- X versions 4.5 through 4.7 of VAX/VMS. The target zoo.exe
- X directs the linker to use the file options.opt so that the
- X shareable library is used. The target zoobig.exe is identical
- X except that the shareable library is not used, making the exe-
- X cutable program about twice as big.
- X
- X Special techniques are needed to work around numerous pecu-
- X liarities in VAX/VMS. These are described separately in the
- X file ``vmsbugs.doc''. In particular, the VAX/VMS version of
- X zoo must be used in conjunction with the "bilf.exe" utility,
- X which performs needed file conversions. The source program
- X bilf.c is included in the current source distribution for zoo.
- X
- XThe file ``options.h'' defines preprocessor symbols for the various sys-
- Xtems. In most cases, given a reasonably powerful C compiler and
- Xlibrary, you will be able to find a combination of options that will
- Xwork. Documentation for these options is in the file ``options.doc''.
- X
- XOther machine-dependent code and definitions are in machine.h,
- Xmachine.c, and portable.h. Also, the amount of memory used for various
- Xarrays can be customized by defining symbols that are described and used
- Xin zoomem.h.
- X
- XThe low-level input/output routines are in portable.c. In most cases
- Xthese will not need to be modified.
- X
- XThe zoo source code largely conforms to the requirements of Kernighan
- Xand Ritchie's book. Some exceptions are as follows.
- X
- X - Variables are believed to be unique in their initial 8 characters.
- X Systems that distinguish fewer than 8 initial characters are
- X currently not supported.
- X
- X - Zoo code assumes that members of structures do not have global
- X scope.
- X
- X - Long preprocessor symbols are occasionally used.
- X
- X - The special value -1 is cast to a pointer of type (FILE *) to pro-
- X vide a distinguished file pointer that is used to signify output to
- X a null file. This should work on most systems that support the
- X system call sbrk. Any suitable value may be supplied in place of
- X -1 in zooio.h.
- X
- XTROUBLESHOOTING.
- X
- XAs currently configured for **IX variants, zoo uses the access() system
- Xcall to check for file existence (see the definition for the symbol
- XEXISTS in options.h). There is some question about the appropriatenes
- Xof this, because access() can give the wrong answer when used from a
- Xset-user-id program. If EXISTS is left undefined, zoo uses its own
- Xfunction to test for file existence by trying to open the file for read
- Xand also for write.
- X
- XTwo common reasons for crashes when zoo is executed are the following.
- X
- X - On machines with older (Intel-style) architectures zoo requires the
- X large memory model. Compiling with the small memory model will
- X cause problems. Also, systems that are limited to 64 kilobytes of
- X data and 64 kilobytes of code are not currently supported (but they
- X will be in the future).
- X
- X - A generous amount of stack space is needed. Depending on the sys-
- X tem, this will vary from about 15 kilobytes to about 33 kilobytes.
- X On systems that cannot expand the stack dynamically you will need
- X to specify the size of the stack area at load time.
- X
- XSPECIAL VERSIONS. A version (currently 2.01) is available for MS-DOS
- Xthat provides better performance due to assembly language routines and
- Xalso includes some system-dependent features. Another version
- X(currently 2.00) has been ported by J. Brian Waters for the Amiga. It
- Xincludes several AmigaDOS-dependent features such as preservation of
- Xfile times and wildcard expansion.
- X
- XEXTRACT-ONLY VERSIONS. For a new system, your first concern should be
- Xthe ability to extract and list zoo archives. For this purpose try com-
- Xpiling booz (which stands for Barebones Ooz) (currently version 1.01),
- Xwhich can be compiled with three different options requiring different
- Xdegrees of compiler sophistication and offering different levels of
- Xfeatures. Unlike zoo, booz will work on systems with less than 64 kilo-
- Xbytes of total available memory. However, unlike zoo, booz uses low-
- Xlevel unbuffered file descriptors in **IX style. This program is not a
- Xpart of the standard zoo distribution, because nobody has ever shown any
- Xinterest in it.
- X
- XMachine-dependencies.
- X
- X - Currently the only systems supported are those that can read and
- X write in 8-bit units. The file ``machine.h'' contains a typedef of
- X BYTE, and it must be defined to be an 8-bit quantity.
- X
- X - It is not known whether zoo code as it stands will work on a 1's-
- X complement machine.
- X
- X - The code assumes that type `int' is at least 16 bits long and type
- X `long' is at least 32 bits long. There may be some implicit
- X assumptions that type `char' is exactly 8 bits; I am not sure if
- X this is so. However, type `BYTE' must be exactly 8 bits long.
- X
- X - In accordance with K&R (p 126), zoo code assumes that sizeof(char)
- X equals exactly 1.
- X
- X -- Rahul Dhesi 1988/08/25
- END_OF_FILE
- if test 7622 -ne `wc -c <'Install'`; then
- echo shar: \"'Install'\" unpacked with wrong size!
- fi
- # end of 'Install'
- fi
- if test -f 'bilf.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bilf.c'\"
- else
- echo shar: Extracting \"'bilf.c'\" \(6109 characters\)
- sed "s/^X//" >'bilf.c' <<'END_OF_FILE'
- X/*
- XThis program performs conversion of files between stream-LF format
- X(as used by zoo) and fixed-length record binary format (used for Kermit
- Xtransfers of zoo archives).
- X
- XThis program is:
- X (C) Copyright 1987 Rahul Dhesi.
- X All Rights Reserved.
- X
- XPermission is hereby granted to copy and modify this for any purpose,
- Xwhether commercial or noncommercial, provided only that the above
- Xcopyright notice and this paragraph be preserved and included
- Xin all copies.
- X
- X -- Rahul Dhesi 1987/07/25
- X*/
- X
- X#include <stdio.h>
- X#include <ssdef.h>
- X#define STAT_NORM SS$_NORMAL
- X#define STAT_ABORT SS$_ABORT
- X
- Xchar *strrchr();
- Xchar *strdup ();
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char *inname;
- X char *outname;
- X char *option;
- X int status;
- X
- X if (argc < 3 || argc > 4) {
- X printf ("BILF version 1.00 for VAX/VMS by Rahul Dhesi (1987/07/25)\n\n");
- X printf ("(C) Copyright 1987 Rahul Dhesi, All Rights Reserved\n");
- X printf ("Permission to use and distribute is granted provided this copyright\n");
- X printf ("notice is preserved and included in all copies.\n\n");
- X printf ("Usage: BILF {lb} infile [ outfile ]\n\n");
- X printf ("Choose one character from within braces. If outfile is not supplied\n");
- X printf ("it has the same name as infile but a higher version number.\n");
- X printf ("Options are:\n\n");
- X printf ("l: Write output file in stream-LF format. This is the format that\n");
- X printf (" zoo expects all zoo archives to be in. If a zoo archive was\n");
- X printf (" uploaded to a VAX/VMS system, it will need to be converted to\n");
- X printf (" stream-LF format before manipulating with zoo.\n\n");
- X printf ("b: Write output file in fixed-length 512-byte binary record format. Before\n");
- X printf (" a zoo archive can be downloaded from a VAX/VMS system to a\n");
- X printf (" microcomputer using VAX/VMS Kermit, it must be converted to\n");
- X printf (" this binary format. Failure to do so will result in a corrupted\n");
- X printf (" download.\n");
- X exit (STAT_NORM);
- X }
- X
- X inname = argv[2];
- X option = argv[1];
- X
- X if (argc == 3) { /* use same filename for output */
- X char *p;
- X outname = strdup (inname);
- X p = strrchr (outname, ';'); /* strip trailing version field */
- X if (p != NULL)
- X *p = '\0';
- X } else
- X outname = argv[3];
- X
- X if (*option == 'l')
- X status = cvtstream (outname, inname);
- X else if (*option == 'b')
- X status = cvtbin (outname, inname);
- X else
- X prterror ('f', "Option %s is invalid\n", option);
- X if (status == -1)
- X prterror ('w', "An error occurred -- output file may be corrupted\n");
- X exit (STAT_NORM);
- X}
- X
- X#define MYBUFSIZ 8192
- X
- X/* writes input file to output file in stream format */
- Xint cvtstream (outname, inname)
- Xchar *outname, *inname;
- X{
- X FILE *infile, *outfile;
- X char buffer[MYBUFSIZ];
- X int count;
- X
- X infile = fopen (inname, "r");
- X if (infile == NULL)
- X prterror ('f', "Could not open input file %s\n", inname);
- X outfile = fopen (outname, "w");
- X if (outfile == NULL)
- X prterror ('f', "Could not open output file %s\n", outname);
- X
- X while ((count = fread (buffer, 1, sizeof (buffer), infile)) > 0)
- X count = fwrite (buffer, 1, count, outfile);
- X
- X close (infile); close (outfile);
- X if (count == -1)
- X return (-1);
- X else
- X return (0);
- X}
- X
- X/*
- XVMS C doesn't have strdup().
- X*/
- Xchar *strdup (str)
- Xchar *str;
- X{
- X char *malloc();
- X char *newstr = malloc (strlen (str) + 1);
- X if (newstr != NULL) {
- X strcpy (newstr, str);
- X return (newstr);
- X } else
- X return ((char *) NULL);
- X}
- X
- X/* BLKSIZ must correspond to block size specified below in creat() */
- X#define BLKSIZ 512
- X
- X/*
- XWrites input file to output in fixed-length BLKSIZ-byte record format.
- X*/
- X
- X#if 1
- X#include <file.h>
- X#else
- X#include <fcntl.h>
- X#endif
- X
- Xint convert ();
- X
- Xint cvtbin (outname, inname)
- Xchar *outname, *inname;
- X{
- X int status, inhan, outhan;
- X inhan = open (inname, O_RDONLY);
- X if (inhan == -1)
- X prterror ('f', "Could not open input file %s\n", inname);
- X outhan = creat (outname, 0, "rfm=fix", "mrs=512");
- X if (outhan == -1)
- X prterror ('f', "Could not open output file %s\n", outname);
- X status = convert (outhan, inhan);
- X close (inhan);
- X close (outhan);
- X return (status);
- X}
- X
- X/*
- XFunction convert() reads from inhan and writes to outhan, always
- Xwriting in BLKSIZ-byte blocks, padding with nulls if necessary
- X*/
- X
- Xint convert (outhan, inhan)
- Xint inhan, outhan;
- X{
- X char junk[BLKSIZ];
- X int count;
- X int done = 0;
- X do {
- X count = vmsread (inhan, junk, BLKSIZ);
- X if (count <= 0)
- X break;
- X if (count < BLKSIZ) {
- X int i;
- X for (i = count; i < BLKSIZ; i++)
- X junk[i] = 0;
- X done++;
- X }
- X count = write (outhan, junk, BLKSIZ);
- X if (count == -1)
- X break;
- X } while (!done);
- X if (count == -1)
- X return (-1);
- X else
- X return (0);
- X}
- X
- X/**** Function vmsread() does a standard read() but gets around bugs
- Xin the read() function of VAX/VMS C which make it unable to always
- Xread the entire amount requested in a single read() call.
- X*/
- Xint vmsread (han, buf, amount)
- Xint han;
- Xchar *buf;
- Xint amount;
- X{
- X int count;
- X int thiscount;
- X count = 0;
- X while (count != -1 && count < amount) {
- X thiscount = read (han, &buf[count], amount - count);
- X if (thiscount == 0)
- X thiscount = read (han, &buf[count], amount - count);
- X if (thiscount == 0)
- X break;
- X if (thiscount == -1)
- X count = -1;
- X else
- X count += thiscount;
- X }
- X return (count);
- X}
- X
- Xprterror (level, msg1, msg2)
- Xchar level;
- Xchar *msg1, *msg2;
- X{
- X if (level == 'e' || level == 'w' || level == 'f')
- X printf ("BILF: ");
- X
- X switch (level) {
- X case 'e': printf ("ERROR: "); break;
- X case 'w': printf ("WARNING: "); break;
- X case 'f': printf ("FATAL: "); break;
- X default: prterror ('f', "Internal error in prterror()\n");
- X }
- X
- X printf (msg1, msg2);
- X if (level == 'f')
- X exit (STAT_ABORT);
- X}
- END_OF_FILE
- if test 6109 -ne `wc -c <'bilf.c'`; then
- echo shar: \"'bilf.c'\" unpacked with wrong size!
- fi
- # end of 'bilf.c'
- fi
- if test -f 'fiz.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fiz.c'\"
- else
- echo shar: Extracting \"'fiz.c'\" \(6864 characters\)
- sed "s/^X//" >'fiz.c' <<'END_OF_FILE'
- X#ifndef LINT
- Xstatic char sccsid[]="@(#) fiz.c 2.6 88/01/31 23:23:50";
- X#endif /* LINT */
- X
- X/*
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1987/02/06
- X*/
- X
- X/*
- XSearches for all directory entries in an archive and prints their
- Xoffsets. Zoo 1.41 and later may then be asked to extract a specific
- Xfile by supplying the offset of the file.
- X*/
- X
- X#include "options.h"
- X#include "zooio.h"
- X#include "various.h"
- X#include "zoofns.h"
- X#include "portable.h" /* I/O definitions */
- X#include "zoo.h"
- X
- X#ifdef LINT_ARGS
- Xvoid prtctrl (char *);
- Xvoid prtch (unsigned int);
- X#else
- Xvoid prtctrl ();
- Xvoid prtch ();
- X#endif
- X
- Xmain(argc,argv)
- Xregister int argc;
- Xregister char **argv;
- X{
- X char *zooname; /* name of archive to be read */
- X ZOOFILE zoo_file; /* the archive being examined opened for read */
- X int state; /* to keep track of how much of tag seen */
- X int inch; /* char just read from archive */
- X
- X static char usage1[] = "Fiz 2.0 (1987/02/01) public domain Zoo archive repair utility by Rahul Dhesi\n";
- X static char usage2[] = "Usage: fiz archive[.zoo] (\"fiz -h\" for help)\n";
- X
- X#ifdef SETBUF
- X/* set stdout to unbuffered */
- Xsetbuf (stdout, (char *) NULL);
- X#endif
- X
- X if (argc < 2) {
- X printf("%s%s", usage1, usage2);
- X exit (1);
- X }
- X
- X if (strcmp(argv[1],"-h") == 0)
- X goto givehelp;
- X
- X zooname = argv[1];
- X
- X /* Add default extension if none supplied */
- X {
- X char *p, *q;
- X p = zooname + strlen(zooname); /* point to last char */
- X while (p != zooname && *p != EXT_CH)
- X --p;
- X /* either found EXT_CH or reached beginning of zooname */
- X if (*p != EXT_CH) {
- X q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
- X if (q == NULL) {
- X printf("Fiz: Ran out of memory.\n");
- X exit(1);
- X }
- X strcpy(q, zooname);
- X strcat(q, EXT_DFLT);
- X zooname = q;
- X }
- X }
- X
- X zoo_file = zooopen (zooname, Z_READ);
- X if (zoo_file == NOFILE) {
- X printf("Fiz: FATAL: Could not open %s.\n", zooname);
- X exit(1);
- X }
- X
- X#ifdef DOUBLE_SECRET
- X { void oh_well(void); oh_well(); }
- X#endif
- X
- X#define NOSTATE 1
- X#define HDR_1 0xdc
- X#define HDR_2 0xa7
- X#define HDR_3 0xc4
- X#define HDR_4 0xfd
- X
- X#define DAT_1 '@'
- X#define DAT_2 ')'
- X#define DAT_3 '#'
- X#define DAT_4 '('
- X
- X/* finite state machine implemented here by hand */
- X
- X state = NOSTATE;
- X while ((inch = zgetc(zoo_file)) != EOF) {
- X inch = inch & 0xff;
- X if (state == NOSTATE) {
- X if (inch == HDR_1)
- X state = HDR_1;
- X else if (inch == DAT_1)
- X state = DAT_1;
- X } else if (state == HDR_1 && inch == HDR_2)
- X state = HDR_2;
- X else if (state == HDR_2 && inch == HDR_3)
- X state = HDR_3;
- X else if (state == HDR_3 && inch == HDR_4)
- X state = HDR_4;
- X else if (state == DAT_1 && inch == DAT_2)
- X state = DAT_2;
- X else if (state == DAT_2 && inch == DAT_3)
- X state = DAT_3;
- X else if (state == DAT_3 && inch == DAT_4)
- X state = DAT_4;
- X else
- X state = NOSTATE;
- X
- X if (state == HDR_4) { /* found archive tag */
- X long save_pos;
- X struct direntry direntry;
- X save_pos = zootell(zoo_file);
- X zooseek(zoo_file, save_pos-4L, 0); /* back to tag pos */
- X frd_dir(&direntry, zoo_file); /* read dir entry */
- X printf("****************\n");
- X
- X printf ("%8lu: DIR ", save_pos-4L);
- X
- X if (direntry.dirlen > 0) {
- X printf ("[");
- X prtctrl (direntry.dirname);
- X printf ("]");
- X }
- X
- X printf(" [");
- X prtctrl (direntry.fname);
- X printf ("]");
- X
- X if (direntry.namlen > 0) {
- X printf (" [");
- X prtctrl (direntry.lfname);
- X printf ("]");
- X }
- X printf (" ==> %4lu", direntry.offset);
- X if (direntry.dir_crc != 0)
- X printf (" [*bad CRC*]");
- X printf ("\n");
- X fseek (zoo_file, save_pos, 0); /* try again from there */
- X } else if (state == DAT_4) { /* file data */
- X printf ("%8lu: DATA\n", zootell(zoo_file) + 1);
- X }
- X }
- Xexit (0); /* don't fall through */
- X
- Xgivehelp:
- X
- X/*
- Xvi macros:
- Xto add printf:
- X:s/^.*$/printf("&\\n");/
- XTo remove printf:
- X:s/^printf("\(.*\)\\n");/\1/
- X*/
- Xprintf("Fiz is used to help you recover data from a damaged archive. Fiz searches\n");
- Xprintf("the specified archive for directory entries and stored files, and prints the\n");
- Xprintf("position of each one found. Each directory entry contains a number that\n");
- Xprintf("represents the location in the archive where the file is stored; fiz also\n");
- Xprintf("prints this position. All numbers printed are decimal numbers.\n\n");
- X
- Xprintf("Use Zoo version 2.00 or higher to list or extract files in the damaged\n");
- Xprintf("archive starting at a position identified by fiz. For example, you can\n");
- Xprintf("start extracting files from archive \"badarc.zoo\" at position 1098 with the\n");
- Xprintf("command:\n\n");
- X
- Xprintf(" zoo x@1098 badarc\n\n");
- X
- Xprintf("Zoo will ignore the first 1098 bytes of the damaged archive and you should be\n");
- Xprintf("able to recover the undamaged files from the rest of the archive. You can\n");
- Xprintf("also manually specify where to look for the file data with a command like\n\n");
- X
- Xprintf(" zoo x@1098,1153\n\n");
- X
- Xprintf("which tells zoo to use the directory entry at position 1098, but to get the\n");
- Xprintf("actual file data from position 1153 (and not from where the directory entry\n");
- Xprintf("says the data ought to be). See the manuals for fiz and zoo for more details.\n");
- X
- Xexit (0);
- X}
- X
- X/*
- Xprtctrl() prints a string with all unprintable characters converted
- Xto printable form. To avoid the program running astray trying to
- Xprint damaged data, no more than MAXPRT characters are printed.
- XCharacters with the 8th bit set are printed preceded with ~. Control
- Xcharacters are printed preceded with ^. Both ~ and ^ may preced
- Xthe character if a control character has the 8th bit set.
- X*/
- X#define MAXPRT 50
- X
- Xvoid prtctrl (str)
- Xchar *str;
- X{
- X unsigned int ch;
- X int count;
- X count = 0;
- X
- X while (count < MAXPRT && *str != '\0') {
- X ch = (unsigned) *str;
- X prtch(ch);
- X str++;
- X count++;
- X }
- X}
- X
- X/*
- XDoes the actual character printing for prtctrl()
- X*/
- Xvoid prtch(ch)
- Xunsigned int ch;
- X{
- X /* assumes ASCII character set */
- X if (ch < ' ') { /* ^@ through ^_ */
- X printf("^%c", ch + 0x40);
- X } else if (ch == 0x7f) { /* DEL */
- X printf("^?");
- X } else if (ch > 0x7f) { /* 8th bit set */
- X printf("~"); /* .. so precede with ~ */
- X prtch(ch & 0x7f); /* slick recursive call */
- X } else
- X printf("%c", ch); /* plain char */
- X}
- END_OF_FILE
- if test 6864 -ne `wc -c <'fiz.c'`; then
- echo shar: \"'fiz.c'\" unpacked with wrong size!
- fi
- # end of 'fiz.c'
- fi
- if test -f 'makelist.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makelist.c'\"
- else
- echo shar: Extracting \"'makelist.c'\" \(6233 characters\)
- sed "s/^X//" >'makelist.c' <<'END_OF_FILE'
- X#ifndef LINT
- X/* @(#) makelist.c 2.3 88/01/24 12:46:44 */
- Xstatic char sccsid[]="@(#) makelist.c 2.3 88/01/24 12:46:44";
- X#endif /* LINT */
- X
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X(C) Copyright 1988 Rahul Dhesi -- All rights reserved
- X*/
- X
- X#include "options.h"
- X#include "portable.h"
- X#include "errors.i"
- X#include "zoo.h"
- X#include "zooio.h"
- X#include "various.h"
- X
- X#include "zoofns.h"
- X#include "assert.h"
- X#include "debug.h"
- X
- X#ifdef LINT_ARGS
- Xchar *nameptr (char *);
- Xvoid modpath (char *);
- X#else
- Xchar *nameptr();
- Xvoid modpath ();
- X#endif
- X
- X/*******************/
- X/*
- Xmakelist() gets all pathnames corresponding to a set of filespecs and
- Xadds them to a list. Not more than "flistsize" pathnames are added.
- XInto `longest' it returns the length of the longest name added, or
- Xzero if none added.
- X
- XFiles ignore1, ignore2, and ignore3 are not added to the list.
- XA file that is a device/directory is also not added to the list.
- X
- XHowever, if ignore1 is NULL, both these tests are skipped and all files
- Xwill be added to the list.
- X*/
- X
- Xvoid makelist (argc, argv, flist, flistsize, ignore1, ignore2, ignore3, longest)
- Xint argc; /* number of filespec supplied */
- Xchar *argv[]; /* array of pointers to supplied filespecs */
- Xregister char *flist[]; /* array of pointers to filenames we will add */
- Xint flistsize; /* home many names we can use */
- Xchar *ignore1, *ignore2, *ignore3; /* files to exclude from list */
- Xint *longest; /* length of longest name in list */
- X{
- X char *this_path; /* current pathname */
- X int fptr; /* pointer to within flist */
- X register int i, j; /* loop counters */
- X
- X#ifdef WILDCARD
- X char *pat_name; /* filename part of pattern */
- X#endif
- X
- X int gap; /* for Shell sort */
- X
- X flistsize--; /* allow for one terminating NULL entry */
- X fptr = *longest = 0;
- X
- X assert(argc > 0);
- X
- X#define WCLEN 4 /* length needed for wildcard, and a little extra */
- X
- X while (argc > 0) {
- X#ifdef WILDCARD
- X int argok = 0; /* arg not matched yet */
- X#endif
- X char *this_arg;
- X this_arg = emalloc (strlen (*argv) + WCLEN);
- X strcpy (this_arg, *argv);
- X
- X /* Initialize fileset 0. Select all files -- we will later
- X filter out the ones wanted */
- X#ifdef FOLD
- X strlwr (this_arg);
- X#endif
- X
- X#ifdef WILDCARD
- X pat_name = strdup (nameptr (this_arg)); /* pattern without path */
- X#ifdef VER_CH /* trailing version field */
- X{
- X static char version_field[] = " *";
- X char *p;
- X p = strrchr (pat_name, VER_CH);
- X if (p == NULL) {
- X *version_field = VER_CH;
- X pat_name = newcat (pat_name, version_field); /* adds trailing ";*" */
- X }
- X}
- X#endif
- X /*
- X replace filename by wildcard; however, if argument ends in slash,
- X then simply append wildcard so we get all files in that directory
- X */
- X#ifdef FORCESLASH
- X fixslash (this_arg); /* convert backslashes to slashes */
- X#endif
- X
- X if (*lastptr(this_arg) == *PATH_CH) {
- X strcat (this_arg, WILDCARD);
- X pat_name = "*"; /* and select all files */
- X } else
- X#ifdef SPEC_WILD
- X spec_wild (this_arg);
- X#else
- X strcpy (nameptr (this_arg), WILDCARD);
- X#endif /* SPEC_WILD */
- X#endif /* WILDCARD */
- X
- X nextfile (0, this_arg, 0);
- X while (fptr < flistsize &&
- X (this_path = nextfile(1, (char *) NULL, 0)) != NULL) {
- X char *this_name = nameptr (this_path);
- X modpath (this_path); /* do any needed changes to path */
- X
- X#ifdef IGNORECASE
- X#define COMPARE strcmpi
- X#else
- X#define COMPARE strcmp
- X#endif
- X if (ignore1 != NULL) {
- X if (samefile (this_name,ignore1) || /* exclude ignored files */
- X samefile (this_name,ignore2) ||
- X samefile (this_name,ignore3))
- X continue;
- X
- X#ifdef CHEKUDIR
- X if (isuadir(this_path))
- X continue;
- X#else /* CHEKUDIR */
- X# ifdef CHEKDIR
- X if (isfdir(this_path))
- X continue;
- X# endif /* CHEKDIR */
- X#endif /* CHEKUDIR */
- X } /* end if ignore1 ! = NULL */
- X
- X/*
- XIf WILDCARD is defined (e.g. AmigaDOS, MS-DOS, VAX/VMS), then nextfile()
- Xreturns all filenames and we must now select the ones we need by pattern
- Xmatching. If WILDCARD is not defined (e.g. **IX), filenames have already been
- Xselected by the shell and need not be tested again.
- X*/
- X#ifdef WILDCARD
- X if (match_half (this_name,pat_name) ||
- X match_half (pat_name, "?-?") && /* character range */
- X *this_name >= *pat_name && *this_name <= pat_name[2])
- X#endif
- X {
- X#ifdef WILDCARD
- X argok = 1; /* remember arg matched */
- X#endif
- X flist[fptr++] = strdup (this_path);
- X if (*longest < strlen(this_path))
- X *longest = strlen(this_path);
- X }
- X
- X } /* end while */
- X#ifdef WILDCARD
- X if (argok == 0) { /* no match for argument */
- X prterror ('e', "Could not open %s\n", *argv);
- X }
- X#endif
- X argc--;
- X argv++;
- X }
- X /* fptr is now 1 + index of last item in array */
- X
- X if (this_path != NULL && fptr >= flistsize)
- X prterror ('w', too_many_files, flistsize);
- X#ifndef DONT_SORT
- X /* Shell sort -- K&R p. 58 */
- X for (gap = fptr/2; gap > 0; gap /= 2)
- X for (i = gap; i < fptr; i++)
- X for (j = i - gap; j >= 0 &&
- X strcmp(flist[j],flist[j+gap]) > 0; j -= gap) {
- X char *t = flist[j]; flist[j] = flist[j+gap]; flist[j+gap] = t;
- X }
- X#endif /* DONT_SORT */
- X
- X fptr--; /* fptr is now index of last item in array */
- X
- X /* Remove duplicates */
- X for (i = 0; i < fptr; i++) {
- X while (i<fptr && COMPARE(flist[i],flist[i+1]) == 0) {
- X for (j = i; j < fptr; j++)
- X flist[j] = flist[j+1];
- X fptr--;
- X }
- X }
- X
- X flist[++fptr] = NULL; /* NULL entry terminates list */
- X}
- X
- X/*******
- Xmodpath() makes any changes needed before pathname is stored;
- Xcurrently these could involve folding it to lower case and
- Xconverting backslashes to forward slashes
- X*/
- X
- X/*ARGUSED*/
- Xvoid modpath (path)
- Xchar *path;
- X{
- X#ifdef FOLD
- X strlwr (path);
- X#endif
- X
- X#ifdef FORCESLASH
- X fixslash (path); /* convert backslashes to slashes */
- X#endif
- X}
- X
- X#ifdef CHEKDIR
- X/* Function isfdir returns 1 if pathname is a directory else 0 */
- Xint isfdir (this_path)
- Xchar *this_path;
- X{
- X int dir;
- X ZOOFILE f;
- X f = zooopen (this_path, Z_READ);
- X if (f == NOFILE)
- X return 0;
- X else {
- X dir = isadir(f); zooclose(f);
- X }
- X return (dir);
- X}
- X#endif
- END_OF_FILE
- if test 6233 -ne `wc -c <'makelist.c'`; then
- echo shar: \"'makelist.c'\" unpacked with wrong size!
- fi
- # end of 'makelist.c'
- fi
- if test -f 'misc2.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc2.c'\"
- else
- echo shar: Extracting \"'misc2.c'\" \(7457 characters\)
- sed "s/^X//" >'misc2.c' <<'END_OF_FILE'
- X#ifndef LINT
- X/* @(#) misc2.c 2.7 88/01/24 12:47:36 */
- Xstatic char sccsid[]="@(#) misc2.c 2.7 88/01/24 12:47:36";
- X#endif /* LINT */
- X
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X(C) Copyright 1988 Rahul Dhesi -- All rights reserved
- X*/
- X#include "options.h"
- X/* Miscellaneous routines */
- X#include "portable.h"
- X#include "zooio.h"
- X#include "various.h"
- X#include "zoofns.h" /* only for malloc */
- X#include "errors.i"
- X#include "zoomem.h"
- X#include "zoo.h"
- X
- X#ifdef LINT_ARGS
- Xint makepath (char *);
- X#else
- Xint makepath ();
- X#endif
- X
- X
- X/**********************/
- X/* memerr() */
- X/* Give error message on memory error and abort */
- Xvoid memerr()
- X{
- X#ifdef OOZ
- X prterror ('f', no_memory, "", "");
- X#else
- X prterror ('f', no_memory);
- X#endif
- X}
- X
- X/**********************/
- X/*
- Xemalloc() allocates memory like malloc() does, except that it automatically
- Xcalls the error function memerr() if memory couldn't be allocated. It also
- Xassumes (unless small memory allocation is being done) that memory will
- Xnever be freed and conserves it by allocating memory in large chunks
- Xand then partitioning it out with no administrative overhead.
- X*/
- X
- Xchar *emalloc (size)
- Xunsigned int size;
- X{
- X#define BLOCK_SIZE 512 /* memory allocation granularity */
- X
- X#ifdef USE_MALLOC
- X/* Pass on memory requests to malloc() */
- X char *ptr;
- X if ((ptr = malloc (size)) == NULL)
- X memerr();
- X return (ptr);
- X#else
- X static char *memptr;
- X static unsigned avail = 0;
- X unsigned malloc_incr;
- X char *retval;
- X
- X if (size == 0)
- X return (NULL);
- X
- X /* if not enough space avail get some more */
- X if (avail < size) {
- X malloc_incr = BLOCK_SIZE;
- X if (malloc_incr < size)
- X malloc_incr = size;
- X while (malloc_incr >= size && (memptr = malloc (malloc_incr)) == NULL)
- X malloc_incr = (malloc_incr / 6) * 5;
- X avail = malloc_incr;
- X }
- X
- X if (avail < size)
- X memerr(); /* no return from this */
- X retval = memptr;
- X memptr += size;
- X avail -= size;
- X return (retval);
- X#endif /* end of not USE_MALLOC */
- X}
- X
- X/**********************/
- X/* putstr()
- XThis function prints a string to standard output. If the received
- Xstring pointer is NULL, it is handled safely. This function is here
- Xfor historical reasons: Ooz was once coded to not use printf under
- XMSDOS to save space, and at that time putstr() printed a string
- Xwithout using printf. It should eventually be eliminated and all
- Xcalls to it replaced with calls to printf directly.
- X*/
- Xputstr (str)
- Xregister char *str;
- X{
- X if (str == NULL)
- X return;
- X printf ("%s", str);
- X}
- X
- X/**********************/
- X/* exists()
- XThis function checks the existence of a file.
- X
- XIf the symbol EXISTS is defined, that is called as a macro and
- Xsupplied the filename. It must return 1 if the file exists and
- X0 if it does not.
- X
- XIf EXISTS is not defined, exists() tests to see if the file can be
- Xopened for reading or writing; if so, it returns 1 else it returns 0.
- X
- XBecause of the delay between the time existence is checked and the time Zoo
- Xcreates a files, a race condition exists. It would be better to
- Xuse open() with the O_EXCL flag but that will not work for many
- Xsystems.
- X*/
- X
- Xint exists (fname)
- Xchar *fname;
- X{
- X#ifdef EXISTS
- X return EXISTS(fname);
- X#else
- X ZOOFILE f;
- X
- X if ( (f = zooopen (fname, Z_READ )) != NOFILE ||
- X (f = zooopen (fname, Z_WRITE)) != NOFILE ) {
- X zooclose (f);
- X return (1);
- X } else
- X return (0);
- X#endif /* ifdef EXISTS */
- X}
- X
- X/****************
- Xnewcat() allocates enough space to concatenate two strings then returns
- Xa pointer to the concatenated result */
- X
- Xchar *newcat (r, s)
- Xchar *r, *s;
- X{
- X char *temp = emalloc (strlen (r) + strlen (s) + 2); /* 1 spare */
- X strcpy (temp, r);
- X strcat (temp, s);
- X return (temp);
- X}
- X
- X
- X/* Creates a path */
- Xint makepath(path)
- Xchar *path;
- X{
- X char tmppath[PATHSIZE];
- X char *slashpos;
- X if (path == NULL)
- X return;
- X while (*lastptr(path) == *PATH_CH) /* remove trailing slashes */
- X *lastptr(path) = '\0';
- X if (*path == '\0')
- X return;
- X
- X slashpos = findlast(path, PATH_CH); /* find last slash */
- X if (slashpos == NULL) { /* if not, just create dir. */
- X MKDIR(path);
- X return;
- X } else { /* otherwise... */
- X if (slashpos == path) { /* if leading slash */
- X MKDIR(slashpos); /* make that directory */
- X return; /* and done */
- X } else {
- X strcpy(tmppath,path); /* save path */
- X *slashpos = '\0'; /* split into prefix & suffix */
- X#ifdef DEBUG
- X printf("making path from [%s]\n", path);
- X#endif
- X makepath(path); /* make path from prefix */
- X#ifdef DEBUG
- X printf("making dir from [%s]\n", tmppath);
- X#endif
- X MKDIR(tmppath); /* make dir from suffix */
- X }
- X }
- X} /* makepath() */
- X
- X/*
- XIf no extension in filename add supplied extension
- X*/
- Xchar *addext (fname, ext)
- Xchar *fname;
- Xchar *ext;
- X{
- X if (strchr (nameptr (fname), EXT_CH) == NULL)
- X return (newcat (fname, ext));
- X else
- X return (fname);
- X}
- X
- X#ifdef VER_CH /* remove any trailing extension field */
- Xchar *strip_ver (fname)
- Xchar *fname;
- X{
- X char *p = strchr (fname, VER_CH);
- X if (p != NULL)
- X *p = '\0';
- X}
- X#endif
- X
- X/*
- XFunction samefile() compares two filenames to see if they are the
- Xsame file. Just strcmp() or strcmpi() could have been used, except
- Xthat if the filenames have trailing version fields, we want to
- Xcompare those always equal. samefile() is called by routines
- Xthat want to avoid adding an archive to itself.
- X*/
- Xint samefile (f1, f2)
- Xchar *f1;
- Xchar *f2;
- X{
- X#ifdef IGNORECASE
- X#define COMPARE strcmpi
- X#else
- X#define COMPARE strcmp
- X#endif
- X
- X#ifdef VER_CH
- X char tf1[LFNAMESIZE];
- X char tf2[LFNAMESIZE];
- X strcpy (tf1, f1);
- X strcpy (tf2, f2);
- X strip_ver (tf1); /* strip version fields */
- X strip_ver (tf2);
- X return (COMPARE (tf1, tf2) == 0);
- X#else
- X/* if no version fields, just use strcmp(i) */
- X return (COMPARE (f1, f2) == 0);
- X#endif
- X}
- X
- X#ifdef USE_ASCII
- Xint isdigit (c)
- Xchar c;
- X{
- X return (c >= '0' && c <= '9');
- X}
- Xint isupper (c)
- Xchar c;
- X{
- X return (c >= 'A' && c <= 'Z');
- X}
- X
- Xint toascii (c)
- Xchar c;
- X{
- X return (c & 0x7f);
- X}
- X
- Xint tolower (c)
- Xchar c;
- X{
- X return (isupper(c) ? (c | 0x20) : c);
- X}
- X#endif
- X
- X#ifdef GETTZ
- X/****************
- XFunction tzadj() accepts a directory entry and adjusts its timestamp
- Xto reflect its timezone. Uses function mstime() from mstime.i
- Xand mstonix() from nixtime.i.
- X*/
- X
- Xlong mstonix();
- Xlong gettz();
- X#include "mstime.i" /* get mstime() */
- X
- Xvoid tzadj (direntry)
- Xstruct direntry *direntry;
- X{
- X long diff_tz;
- X long longtime;
- X if (direntry->tz == NO_TZ) /* none stored */
- X return;
- X diff_tz = (long) direntry->tz * (3600/4) - gettz(); /* diff. in seconds */
- X longtime = mstonix (direntry->date, direntry->time) + diff_tz; /* adj tz */
- X mstime (longtime, &direntry->date, &direntry->time);
- X}
- X#endif /* GETTZ */
- X
- X/* how long an int can be in text form -- allow 64-bit ints */
- X#define INT_TEXT 21
- X
- X/* Function add_version adds a version suffix to a filename, given
- Xthe directory entry corresponding to the file */
- Xvoid add_version (fname, direntry)
- Xchar *fname;
- Xstruct direntry *direntry;
- X{
- X char verstr[INT_TEXT]; /* string buffer for conversion to text */
- X if (direntry->vflag & VFL_ON) {
- X sprintf (verstr, "%u", direntry->version_no);
- X strcat (fname, VER_DISPLAY);
- X strcat (fname, verstr);
- X }
- X}
- END_OF_FILE
- if test 7457 -ne `wc -c <'misc2.c'`; then
- echo shar: \"'misc2.c'\" unpacked with wrong size!
- fi
- # end of 'misc2.c'
- fi
- if test -f 'parse.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'parse.c'\"
- else
- echo shar: Extracting \"'parse.c'\" \(5640 characters\)
- sed "s/^X//" >'parse.c' <<'END_OF_FILE'
- X#ifndef LINT
- Xstatic char sccsid[]="@(#) parse.c 2.1 87/12/25 12:24:10";
- X#endif /* LINT */
- X
- X/*
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- X
- X*/
- X
- X#include "options.h"
- X#include "zoo.h"
- X#include "zooio.h"
- X#include "various.h"
- X#include "zoofns.h"
- X
- X#include "parse.h"
- X#include "assert.h"
- X
- X/*
- Xparse() accepts a filename and return its component parts in a structure.
- XThe component parts are: disk drive, path prefix, root name of filename,
- Xand extension.
- X
- XIf DISK_CH is not defined, it is assumed that filenames may be
- Xpreceded with a disk prefix terminated by the character DISK_CH.
- XThe first character of the disk prefix, followed by DISK_CH,
- Xis returned in the drive field.
- X
- XIf the symbol DISK_CH is defined, a null string is returned in the
- Xdisk field.
- X*/
- Xvoid parse (path_st, fname)
- Xregister struct path_st *path_st;
- Xchar *fname;
- X{
- X char tempname[LFNAMESIZE]; /* working copy of supplied fname */
- X char *namep; /* points to relevant part of tempname */
- X
- X char *p;
- X strcpy (tempname, fname);
- X
- X#ifdef DEBUG
- Xprintf ("parse: supplied name is [%s].\n", tempname);
- X#endif
- X
- X#ifndef DISK_CH
- X path_st->drive[0] = '\0';
- X namep = tempname; /* points to pathname+filename */
- X#else
- X path_st->drive[0] = '\0';
- X p = strchr (tempname, DISK_CH); /* point to first ':' */
- X
- X if (p != NULL) {
- X path_st->drive[0] = *tempname;/* use only first char of drive name */
- X path_st->drive[1] = DISK_CH;
- X path_st->drive[2] = '\0';
- X namep = ++p; /* point to pathname+filename */
- X } else {
- X path_st->drive[0] = '\0';
- X namep = tempname; /* points to pathname+filename */
- X }
- X#endif /* end of not DISK_CH */
- X
- X /* Note: findlast() finds last occurrence in the subject string of
- X any one of a set of chars */
- X
- X /* save the long filename */
- X p = findlast (namep, PATH_SEP);
- X
- X /* if path separator found, copy next char onwards; else entire string */
- X strncpy (path_st->lfname,
- X (p != NULL) ? p+1 : namep,
- X LFNAMESIZE);
- X path_st->lfname[LFNAMESIZE-1] = '\0'; /* force null termination */
- X
- X#ifdef DEBUG
- Xprintf ("parse: path = [%s] long filename = [%s]\n",
- X namep, path_st->lfname);
- X#endif
- X
- X/* Separate out the extension */
- Xp = findlast (namep, EXT_SEP); /* look for . or / */
- Xif (p != NULL && *p != EXT_CH) /* found .? */
- X p = NULL; /* ... if not, ignore / */
- X
- X#ifdef DEBUG
- Xif (p == NULL)
- X printf ("parse: no extension found for [%s]\n", namep);
- Xelse
- X printf ("parse: extension for [%s] is [%s]\n", namep, p);
- X#endif
- X
- X path_st->ext[0] = '\0'; /* assume no extension */
- X if (p != NULL) { /* found extension */
- X strncpy (path_st->ext, (p+1), EXTLEN); /* save extension */
- X path_st->ext[EXTLEN] = '\0'; /* force termination */
- X *p = '\0'; /* null out extension */
- X }
- X
- X /* separate out root of filename if any */
- X p = findlast (namep, PATH_SEP);
- X
- X if (p != NULL) {
- X ++p;
- X strncpy (path_st->fname, p, ROOTSIZE); /* save filename */
- X *p = '\0'; /* null out filename */
- X } else {
- X strncpy (path_st->fname, namep, ROOTSIZE);
- X *namep = '\0'; /* null out filename */
- X }
- X path_st->fname[ROOTSIZE] = '\0'; /* force termination */
- X
- X /* what remains, whether null or not, is the path prefix */
- X path_st->dir[0] = '\0'; /* in case *namep is '\0' */
- X
- X strncpy (path_st->dir, namep, PATHSIZE);
- X
- X /* remove trailing path-separater from directory name, but don't
- X remove it if it is also the leading separater */
- X {
- X int n;
- X n = strlen(path_st->dir);
- X if (n != 1)
- X path_st->dir[n-1] = '\0';
- X }
- X
- X#ifdef DEBUG
- Xprintf ("parse: path prefix = [%s].\n", namep);
- X#endif
- X /* if extension is null, and if long filename contains more than
- X ROOTSIZE characters, transfer some of them to extension */
- X if (path_st->ext[0] == '\0' && strlen(path_st->lfname) > ROOTSIZE) {
- X strncpy(path_st->ext, &path_st->lfname[ROOTSIZE], EXTLEN);
- X path_st->ext[3] = '\0';
- X }
- X}
- X
- X/*******************/
- X/*
- Xfindlast() finds last occurrence in provided string of any of the characters
- Xexcept the null character in the provided set.
- X
- XIf found, return value is pointer to character found, else it is NULL.
- X*/
- X
- Xchar *findlast (str, set)
- Xregister char *str; /* subject string */
- Xchar *set; /* set of characters to look for */
- X
- X{
- X register char *p;
- X
- X if (str == NULL || set == NULL || *str == '\0' || *set == '\0')
- X return (NULL);
- X
- X p = lastptr (str); /* pointer to last char of string */
- X assert(p != NULL);
- X
- X while (p != str && strchr (set, *p) == NULL) {
- X --p;
- X }
- X
- X /* either p == str or we found a character or both */
- X if (strchr (set, *p) == NULL)
- X return (NULL);
- X else
- X return (p);
- X}
- X
- X/*******************/
- X/*
- Xlastptr() returns a pointer to the last non-null character in the string, if
- Xany. If the string is null it returns NULL
- X*/
- X
- Xchar *lastptr (str)
- Xregister char *str; /* string in which to find last char */
- X{
- X register char *p;
- X if (str == NULL)
- X prterror ('f', "lastptr: received null pointer\n");
- X if (*str == '\0')
- X return (NULL);
- X p = str;
- X while (*p != '\0') /* find trailing null char */
- X ++p;
- X --p; /* point to just before it */
- X return (p);
- X}
- END_OF_FILE
- if test 5640 -ne `wc -c <'parse.c'`; then
- echo shar: \"'parse.c'\" unpacked with wrong size!
- fi
- # end of 'parse.c'
- fi
- if test -f 'prterror.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'prterror.c'\"
- else
- echo shar: Extracting \"'prterror.c'\" \(5399 characters\)
- sed "s/^X//" >'prterror.c' <<'END_OF_FILE'
- X#ifndef LINT
- X/* @(#) prterror.c 2.8 88/01/31 18:48:17 */
- Xstatic char sccsid[]="@(#) prterror.c 2.8 88/01/31 18:48:17";
- X#endif /* LINT */
- X
- X/*
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- X
- X*/
- X#include "options.h"
- X#ifndef OK_STDIO
- X#include <stdio.h>
- X#define OK_STDIO
- X#endif
- X#include "various.h"
- X/* General error handler. Input format:
- X
- X parameter 1: 'w', 'e', or 'f'.
- X
- X 'm': message
- X 'M': message without preceding identification
- X 'w': WARNING
- X 'e': ERROR
- X 'f': FATAL
- X 'F': FATAL but program doesn't exist immediately
- X
- X All text printed is preceded by "Zoo: " or "Ooz: " depending
- X upon conditional compilation, except in the case of 'M' messages
- X which are printed without any text being added.
- X
- X For messages, the text supplied is printed if and only if the global
- X variable "quiet" is zero. Control then returns to the caller.
- X
- X For warnings, errors, and fatal errors, the variable "quiet" is used
- X as follows. Warning messages are suppressed if quiet > 1; error
- X messages are suppressed if quiet > 2. Fatal error messages are
- X never suppressed--doing so would be a bit risky.
- X
- X For warnings and errors, the error message is preceded by the "WARNING:"
- X or "ERROR". The error message is printed and control returns to the
- X caller.
- X
- X For fatal errors, the error message is preceded by "FATAL:" and an
- X error message is printed. If the option was 'f', the program exits with
- X a status of 1. If the option was 'F', control returns to the caller and
- X it is assumed that the caller will do any cleaning up necessary and then
- X exit with an error status.
- X
- X parameter 2: The format control string for printf.
- X parameters 3 and 4 are passed along to printf.
- X
- X NOTE
- X (a) printf() is always supplied parameters 3 through 6, even if they
- X were not on the parameter list passed to prterror(). It is assumed
- X that printf() will only use as many as are specified by the format
- X string. There is a small chance that on some machines, this will cause
- X some kind of stack exception (e.g. if the hardware maintains tag
- X bits in each word on the stack and doesn't allow certain types of
- X data to be arbitrarily accessed). This is just a theory so far.
- X
- X (b) Parameter passing relies on consecutive small parameters being
- X properly interpreted as a single larger parameter when needed.
- X Eventually var_args should be used, but not all systems probably
- X have it at the moment.
- X
- X (c) All messages, whether informative or error, are sent to standard
- X output via printf. It might be a good idea to eventually send 'e' and
- X 'f' class messages to the standard error stream. Best would be
- X some way of telling if standard output and standard error are not
- X the same device, so that we could always send error messages to
- X standard error, and also duplicate them to standard output if
- X different from standard error. There seems to be no way
- X of doing this in the general case.
- X*/
- X
- Xextern int quiet;
- X
- X/* These declarations must be equivalent to those in errors.i */
- Xchar no_match[] = "No files matched.\n";
- Xchar failed_consistency[] = "Archive header failed consistency check.\n";
- Xchar invalid_header[] = "Invalid or corrupted archive.\n";
- Xchar internal_error[]="Internal error.\n";
- Xchar disk_full[] = "I/O error or disk full.\n";
- Xchar bad_directory[] = "Directory entry in archive is invalid.\n";
- Xchar no_memory[] = "Ran out of memory.\n";
- Xchar too_many_files[] = "Some filenames ignored -- can only handle %d.\n";
- Xchar packfirst[] = "Old format archive -- please pack first with P command.\n";
- Xchar garbled[] = "Command is garbled.\n";
- Xchar start_ofs[] = "Starting at %ld (offset %ld)\n";
- X
- X#ifndef OOZ
- Xchar wrong_version[]=
- X "Zoo %d.%d or later is needed to fully manipulate this archive.\n";
- Xchar cant_process[] =
- X "The rest of the archive (%lu bytes) cannot be processed.\n";
- Xchar option_ignored[] = "Ignoring option %c.\n";
- Xchar inv_option[] = "Option %c is invalid.\n";
- Xchar bad_crc[] = "\007Bad CRC, %s probably corrupted\n";
- X#endif
- X
- X#ifdef OOZ
- Xchar could_not_open[] = "Could not open ";
- X#else
- Xchar could_not_open[] = "Could not open %s.\n";
- X#endif
- X
- X#ifdef LINT_ARGS
- X/* defined in zoofns.h but we don't want to include that and waste time */
- Xvoid prterror (int, char *, MORE);
- Xvoid zooexit (int);
- X#endif
- X
- X
- X/*VARARGS2*/
- Xvoid prterror(level, format, a, b, c, d)
- Xregister int level;
- Xchar *format, *a, *b, *c, *d;
- X
- X{
- X char string[120]; /* local format string */
- X *string = '\0'; /* get a null string to begin with */
- X
- X#ifdef OOZ
- X strcpy (string, "Ooz: ");
- X#else
- X strcpy (string, "Zoo: ");
- X#endif
- X
- X switch (level) {
- X case 'M': *string = '\0'; /* fall through to 'm' */
- X case 'm': if (quiet) return; break;
- X case 'w':
- X if (quiet > 1) return;
- X strcat (string, "WARNING: "); break;
- X case 'e':
- X if (quiet > 2) return;
- X strcat (string, "ERROR: "); break;
- X case 'F':
- X case 'f': strcat (string, "FATAL: "); break;
- X default: prterror ('f', internal_error); /* slick recursive call */
- X }
- X
- X strcat (string, format); /* just append supplied message */
- X
- X printf (string, a, b, c, d); /* and print the whole thing */
- X fflush (stdout);
- X
- X if (level == 'f') /* and abort on fatal error 'f' but not 'F' */
- X zooexit (1);
- X}
- END_OF_FILE
- if test 5399 -ne `wc -c <'prterror.c'`; then
- echo shar: \"'prterror.c'\" unpacked with wrong size!
- fi
- # end of 'prterror.c'
- fi
- echo shar: End of archive 3 \(of 10\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-